home *** CD-ROM | disk | FTP | other *** search
-
- /*
- File: TransferModeLibrary.c
-
- Contains: graphics libraries - transfer mode library
-
- Written by: Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 5/1/95 jtd bringing in final 1.1 source changes
- <1> 1/9/95 JD First checked in.
- */
-
- #include <Memory.h>
- #include "GraphicsLibraries.h"
-
- static void InitColorMatrix(Fixed m[5][4])
- {
- register Fixed *x;
- register short i;
-
- x = &m[0][0];
- for(i = 19; i>=0; i--)
- *x++ = 0;
- m[0][0] = m[1][1] = m[2][2] = m[3][3] = fixed1; /* Identity matrix, for cleanliness */
- }
-
- /*
- * Initialize all fields of a transfermode record
- * to a very reasonable rgb copy mode.
- */
- void InitTransferMode(gxTransferMode *mode)
- {
- NilParamReturn(mode);
- SetCommonTransfer(mode,gxCopyMode,0,nil);
- }
-
- gxTransferMode *SetCommonTransfer(register gxTransferMode *mode, commonTransferMode type, unsigned short opValue, const gxColor *opColor)
- {
- register gxTransferComponent *component;
- register short i;
- gxColor oColor;
-
- NilParamReturnNil(mode);
-
- if(opColor)
- {
- oColor = *opColor;
- GXConvertColor(&oColor,gxRGBASpace, nil, nil);
- }
- else
- {
- oColor.space = gxRGBASpace;
- oColor.element.rgba.red =
- oColor.element.rgba.green =
- oColor.element.rgba.blue = opValue;
- oColor.element.rgba.alpha = 65535;
- }
-
- if(type >= gxOverMode && type <= gxFadeMode)
- mode->space = gxRGBASpace;
- else
- mode->space = gxRGBSpace;
-
- mode->flags = 0;
- mode->set = nil;
- mode->profile = nil;
-
- component = &mode->component[0];
- InitColorMatrix(mode->sourceMatrix);
- InitColorMatrix(mode->deviceMatrix);
- InitColorMatrix(mode->resultMatrix);
-
- component->mode = type;
- component->flags = 0;
-
- component->sourceMinimum = component->deviceMinimum = component->clampMinimum = 0;
- component->sourceMaximum = component->deviceMaximum = component->clampMaximum = 65535;
-
- for(i = 3; i>=0; i--)
- {
- component = &mode->component[i];
-
- *component = mode->component[0];
- component->operand = (&oColor.element.rgb.red)[i];
-
- switch(type)
- {
- case gxHighlightMode:
- if(!opColor) /* if no opColor passed, use lomem RGBHilite */
- component->operand = ((short *)0xDA0)[i];
- break;
- case gxOverMode: /* use it like a real alpha mode */
- if(i==3)
- component->mode = gxRampOrMode;
- break;
- case gxAtopMode: /* use it like a real alpha mode */
- if(i==3)
- {
- component->flags |= gxReverseComponent;
- component->mode = gxCopyMode; /* result alpha = device alpha */
- }
- break;
- case gxExcludeMode: /* use it like a real alpha mode */
- if(i==3)
- component->mode = gxRampXorMode;
- break;
- case gxFadeMode:
- if(i==3)
- component->mode = gxAddMode;
- break;
- case commonAddOverMode:
- component->mode = gxAddMode;
- component->flags |= gxOverResultComponent;
- break;
- case commonSubtractOverMode:
- component->mode = gxAddMode;
- component->flags |= gxOverResultComponent;
- mode->sourceMatrix[i][i] = -fixed1;
- break;
- case commonSubtractPinMode:
- component->mode = gxAddMode;
- mode->sourceMatrix[i][i] = -fixed1;
- break;
- case commonTransparentMode: /* the opColor specifies which gxColor to avoid from source */
- component->mode = gxCopyMode;
- mode->flags |= gxRejectSourceTransfer;
- if(opColor)
- {
- component->sourceMinimum =
- component->sourceMaximum = (&oColor.element.rgb.red)[i];
- }
- else /* default is avoid drawing white */
- {
- component->sourceMinimum =
- component->sourceMaximum = 65535;
- }
- break;
- case commonInMode:
- if(i==3)
- component->mode = gxRampAndMode;
- else
- component->mode = gxCopyMode;
- break;
- case commonOutMode:
- if(i==3)
- {
- component->mode = gxRampAndMode;
- mode->deviceMatrix[3][3] = -fixed1;
- mode->deviceMatrix[4][3] = 65535;
- }
- else
- component->mode = gxCopyMode;
- break;
-
-
- }
-
- }
-
- return mode;
- }
-
- void SetInkCommonTransfer(gxInk source, commonTransferMode type)
- {
- gxTransferMode mode;
-
- NilInkReturn(source);
- SetCommonTransfer(&mode, type,32768,nil);
- GXSetInkTransfer(source, &mode);
- }
-
- void SetShapeCommonTransfer(gxShape source, commonTransferMode type)
- {
- gxTransferMode mode;
-
- NilShapeReturn(source);
- SetCommonTransfer(&mode, type,32768,nil);
- GXSetShapeTransfer(source, &mode);
- }
-
- commonTransferMode GetShapeCommonTransfer(gxShape source)
- {
- gxTransferMode mode;
-
- NilShapeReturnNil(source);
- GXGetShapeTransfer(source, &mode);
- return mode.component[0].mode;
- }
-
- commonTransferMode GetInkCommonTransfer(gxInk source)
- {
- gxTransferMode mode;
-
- NilInkReturnNil(source);
- GXGetInkTransfer(source, &mode);
- return mode.component[0].mode;
- }
-
- gxColor *TransmogrifyColor(gxColor *dstColor, const gxColor *srcColor, const gxTransferMode *mode)
- {
- gxInk tempInk = GXNewInk();
-
- GXSetInkColor(tempInk,srcColor);
- GXSetInkTransfer(tempInk,mode);
- GXCombineColor(dstColor, tempInk);
- GXDisposeInk(tempInk);
- return dstColor;
- }
-
- /* Given an gxInk and a device, set's up the gxInk's mode so that drawing over the background gxColor leaves
- * the result gxColor. Also sets up the gxTransferMode gxColorSpace etc. so that the fast case is taken.
- */
- void SetInkFastXorTransfer(gxInk inky, gxViewDevice destDevice, gxViewPort destViewPort, gxColor *background, gxColor *result)
- {
- gxShape deviceBitsShape;
- gxBitmap deviceBits;
- gxTransferMode fastMode;
- gxColor inkColor;
-
- gxColor localBackground;
- gxColor localResult;
-
- localBackground.space = gxRGBSpace;
- localBackground.profile = nil;
- localBackground.element.rgb.red = 0xFFFF;
- localBackground.element.rgb.green = 0xFFFF;
- localBackground.element.rgb.blue = 0xFFFF;
-
- localResult.space = gxRGBSpace;
- localResult.profile = nil;
- localResult.element.rgb.red = 0;
- localResult.element.rgb.green = 0;
- localResult.element.rgb.blue = 0;
-
- if (background)
- localBackground = *background;
- if (result)
- localResult = *result;
-
- deviceBitsShape = GXGetViewDeviceBitmap(destDevice);
- GXGetBitmap(deviceBitsShape, &deviceBits, nil);
-
- if (destViewPort && (GXGetViewPortAttributes(destViewPort) & gxEnableMatchPort) == 0) {
- localBackground.profile = deviceBits.profile; /* if drawing through the viewport will disable color matching, we */
- localResult.profile = deviceBits.profile; /* want to do the same thing for our GXConvertColor calls. */
- }
-
- InitTransferMode(&fastMode);
- fastMode.flags |= gxSingleComponentTransfer;
- fastMode.component[0].mode = gxXorMode;
- if ((fastMode.space = deviceBits.space) == gxIndexedSpace) {
- fastMode.set = deviceBits.set;
- GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
- GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
- if (localBackground.element.indexed.index == localResult.element.indexed.index) {
-
- /* OK, the two colors map into the same index. We will instead use black and white */
- localBackground.space = gxRGBSpace;
- localBackground.profile = nil;
- localBackground.element.rgb.red = 0xFFFF;
- localBackground.element.rgb.green = 0xFFFF;
- localBackground.element.rgb.blue = 0xFFFF;
-
- localResult.space = gxRGBSpace;
- localResult.profile = nil;
- localResult.element.rgb.red = 0;
- localResult.element.rgb.green = 0;
- localResult.element.rgb.blue = 0;
-
- GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
- GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
-
- if (localBackground.element.indexed.index == localResult.element.indexed.index) {
-
- if (localResult.element.indexed.index > 1)
- --localResult.element.indexed.index;
- else
- ++localResult.element.indexed.index; /* This assumes that gxColorSet has at least 2 colors */
- }
- }
- inkColor.space = gxIndexedSpace;
- inkColor.profile = deviceBits.profile;
- inkColor.element.indexed.set = deviceBits.set;
- inkColor.element.indexed.index = ((localBackground.element.indexed.index - 1) ^
- (localResult.element.indexed.index - 1)) + 1;
- } else {
- fastMode.space = gxRGBSpace;
- GXConvertColor(&localBackground, gxRGBSpace, nil, deviceBits.profile);
- GXConvertColor(&localResult, gxRGBSpace, nil, deviceBits.profile);
- inkColor.space = gxRGBSpace;
- inkColor.profile = deviceBits.profile;
- inkColor.element.rgb.red = localBackground.element.rgb.red ^ localResult.element.rgb.red;
- inkColor.element.rgb.green = localBackground.element.rgb.green ^ localResult.element.rgb.green;
- inkColor.element.rgb.blue = localBackground.element.rgb.blue ^ localResult.element.rgb.blue;
- }
- GXSetInkColor(inky, &inkColor);
- GXSetInkTransfer(inky, &fastMode);
- GXDisposeShape(deviceBitsShape);
- }
-
- void SetShapeFastXorTransfer(gxShape source, gxColor *background, gxColor *result)
- {
- long viewPortCount;
-
- viewPortCount = GXGetTransformViewPorts(GXGetShapeTransform(source), nil);
- if( viewPortCount ) {
- gxViewPort vp;
- gxViewDevice vd;
- gxInk inky;
- long viewDeviceCount;
- void *buffer = NewPtr( sizeof(gxViewPort) * viewPortCount );
-
- #ifdef debugging
- if (MemError()) Debugger();
- #endif
- GXGetTransformViewPorts(GXGetShapeTransform(source), (gxViewPort *)buffer);
-
- if( viewDeviceCount = GXGetViewPortViewDevices(vp = *(gxViewPort *)buffer, nil) ) {
- SetPtrSize((Ptr) buffer, viewDeviceCount * sizeof(gxViewDevice));
- if (MemError())
- { DisposePtr((Ptr) buffer);
- buffer = NewPtr(viewDeviceCount * sizeof(gxViewDevice));
- #ifdef debugging
- if (MemError()) Debugger();
- #endif
- }
- GXGetViewPortViewDevices(vp, (gxViewDevice *)buffer);
- vd = *(gxViewDevice *)buffer;
-
- if (GXGetInkOwners(inky = GXGetShapeInk(source)) > 1) {
- GXSetShapeInk(source, inky = GXNewInk());
- GXDisposeInk(inky);
- }
- SetInkFastXorTransfer(inky, vd, vp, background, result);
- GXSetShapeInkAttributes(source, GXGetShapeInkAttributes(source) | gxSuppressDitherInk);
- }
-
- DisposePtr((Ptr) buffer);
- }
- }
-